﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace SqlServerDataExporter
{
    public class HexStringConverter
    {

        /// <summary>
        /// Saves the hexText as a binary file.
        /// </summary>
        /// <param name="file"></param>
        /// <param name="hexText"></param>
        public static void SaveHexString(string file, string hexText)
        {
            byte[] bytes = StringToByteArray(hexText);
            using (FileStream fs = new FileStream(file, FileMode.Create))
            {
                fs.Write(bytes, 0, bytes.Length);
            }          
        }


        /// <summary>
        /// Loads a file and converts it to a hexstring.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string LoadFromFile(string file)
        {
            MemoryStream ms = new MemoryStream();
            using (FileStream fs = new FileStream(file, FileMode.Open))
            {
                byte[] bytes = ReadFully(fs);
                return ByteArrayToString(bytes);
            }  
        }

        /// <summary>
        /// Reads data from a stream until the end is reached. The
        /// data is returned as a byte array. An IOException is
        /// thrown if any of the underlying IO calls fail.
        /// </summary>
        /// <param name="stream">The stream to read data from</param>
        public static byte[] ReadFully(Stream stream)
        {
            byte[] buffer = new byte[32768];
            using (MemoryStream ms = new MemoryStream())
            {
                while (true)
                {
                    int read = stream.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return ms.ToArray();
                    ms.Write(buffer, 0, read);
                }
            }
        }

        /// <summary>
        /// Converts a hexstring to  byte array.
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static byte[] StringToByteArray(string hex)
        {
            if (hex.Length % 2 != 0)
            {
                throw new Exception("String length must be a multiple of 2");
            }
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }

        /// <summary>
        /// Converts a byte array to a hex-string.
        /// </summary>
        /// <param name="ba"></param>
        /// <returns></returns>
        public static string ByteArrayToString(byte[] ba)
        {
            string hex = BitConverter.ToString(ba);
            return hex.Replace("-", "");
        }
    }
}
